package top.jiangqiang.generator;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.map.MapUtil;
import cn.hutool.setting.yaml.YamlUtil;
import cn.hutool.system.SystemUtil;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.config.TemplateType;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import top.jiangqiang.qyblog.common.base.controller.BaseController;
import top.jiangqiang.qyblog.core.base.dao.BaseDao;
import top.jiangqiang.qyblog.core.base.entity.BaseEntity;
import top.jiangqiang.qyblog.core.base.service.BaseService;
import top.jiangqiang.qyblog.core.base.service.impl.BaseServiceImpl;

import java.util.List;

/**
 * @author Jiangqiang
 * @version 1.0
 * @description 生成通用的模板代码
 * @date 2022/7/12 15:05
 */
public class CodeGen {
    /**
     * 作者名字
     */
    private final static String author = "JiangQiang";
    /**
     * 模块名字，自己定义的模块，必须以一定的前缀开头，中间用-分隔，例如qy-spring-boot-starter-system或qy-module-drive
     */
    private final static String moduleName = "qy-blog-core";
    /**
     * 表名的命名规则是模块名的最后一部分+下划线开头，表前缀必须是模块名最后一部分
     */
    private final static List<String> tableNameList = List.of(
            "qy_admin_user",
            "qy_article",
            "qy_draft",
            "qy_article_category",
            "qy_article_tag",
            "qy_category",
            "qy_config",
            "qy_file",
            "qy_link",
            "qy_nav",
            "qy_storage",
            "qy_tag",
            "qy_theme"
    );

    /**
     * 是否覆盖之前的文件 1覆盖所有文件，重新生成 2 只覆盖entity 3 不覆盖
     */
    private final static Integer isOverride = 2;

    /**
     * 如果新建的模块名和表名符合规则，就只需要修改上面的常量即可，此方法不需要修改
     */
    public static void genCode(String url, String username, String password) {
        String baseOutputDir;
        String packageStr;

        baseOutputDir = SystemUtil.getUserInfo().getCurrentDir() + moduleName + "/src/main/";
        packageStr = "top.jiangqiang.qyblog.core";

        FastAutoGenerator.create(url, username, password)
                /*全局配置*/
                .globalConfig(builder -> {
                    builder.author(author) // 设置作者
//                            .enableSwagger() // 开启 swagger 模式
                            .enableSpringdoc() //使用springdoc文档
                            .outputDir(baseOutputDir + "java")// 指定输出目录
                            .disableOpenDir(); //生成之后打开生成目录
                })
                /*包配置*/
                .packageConfig(builder -> {
                    builder.parent(packageStr)// 设置父包名
                            .pathInfo(MapUtil.of(OutputFile.entity, baseOutputDir + "java/top/jiangqiang/qyblog/service/domain/entity"))
                            .entity("domain.entity")
                            .pathInfo(MapUtil.of(OutputFile.xml, baseOutputDir + "resources/mapper/"))
                    ;
                })
                /*模板配置，可以自定义生成模板*/
                .templateConfig(builder -> {
                    builder.disable(TemplateType.ENTITY, TemplateType.SERVICE, TemplateType.SERVICE_IMPL, TemplateType.CONTROLLER, TemplateType.MAPPER, TemplateType.XML)
                            .entity("/templates/entity.java")
                            .service("/templates/service.java")
                            .serviceImpl("/templates/serviceImpl.java")
                            .mapper("/templates/mapper.java")
                            .xml("/templates/mapper.xml")//注释掉后不生成xml文件
                            .controller("/templates/controller.java")
                            .build();
                })
                /*注入配置*/
                .injectionConfig(builder -> {
                })
                /*策略配置*/
                .strategyConfig(builder -> {
                    builder.addInclude(tableNameList) // 设置需要生成的表名
                            .addTablePrefix(
                                    "qy_"
//                                    StrUtil.subAfter(moduleName, "-", true) + "_",
//                                    "sys_",
//                                    "gen_"
                            ); // 设置过滤表前缀
                    builder.entityBuilder().superClass(BaseEntity.class)//设置父类
                            .addIgnoreColumns("id", "create_user", "update_user", "create_time", "update_time")
                            .enableLombok().enableChainModel()
                    ;
                    if (isOverride == 1 || isOverride == 2) {
                        builder.entityBuilder().idType(IdType.ASSIGN_ID)//主键策略
                                .enableFileOverride();// 覆盖已生成文件
                    }
                    builder.mapperBuilder().superClass(BaseDao.class);
                    if (isOverride == 1) {
                        builder.mapperBuilder().enableFileOverride();// 覆盖已生成文件
                    }
                    builder.serviceBuilder().superServiceClass(BaseService.class)
                            .superServiceImplClass(BaseServiceImpl.class);
                    if (isOverride == 1) {
                        builder.serviceBuilder().enableFileOverride();// 覆盖已生成文件
                    }
                    builder.controllerBuilder().superClass(BaseController.class).enableRestStyle();
                    if (isOverride == 1) {
                        builder.controllerBuilder().enableFileOverride();// 覆盖已生成文件
                    }
                })
                /*使用Freemarker引擎模板，默认的是Velocity引擎模板*/
                .templateEngine(new FreemarkerTemplateEngine())
                .execute();
        //删除controller
        FileUtil.del(baseOutputDir + "java/top/jiangqiang/qyblog/core/controller");
    }

    public static void main(String[] args) {
        String currentDir = SystemUtil.getUserInfo().getCurrentDir();
        String configDir = currentDir + "qy-blog-server/src/main/resources/";
        Dict config = YamlUtil.loadByPath(configDir + "application.yaml");
        String active = config.getByPath("spring.profiles.active", String.class);
        Dict activeConfig = YamlUtil.loadByPath(configDir + "application-" + active + ".yaml");
        String url = activeConfig.getByPath("spring.datasource.url");
        String username = activeConfig.getByPath("spring.datasource.username");
        String password = activeConfig.getByPath("spring.datasource.password").toString();
        genCode(url, username, password);
    }
}
